import User from '../models/User.js'
import argon2 from 'argon2'
import jwt from 'jsonwebtoken'
import { secret } from '../config/index.js'
import { userRegex } from '../instrument/regEx/index.js'
import { Op } from 'sequelize'

// 错误处理函数
const handleError = (ctx, message, status = 400) => {
  ctx.status = status
  ctx.body = { message }
}

// 数据验证函数
const validateUserData = async ({ username, password, email }) => {
  const validation = await userRegex({ username, password, email })
  if (!validation.valid) {
    throw new Error(validation.message)
  }
}

// 检查用户名或邮箱是否已存在
const checkUserExists = async ({ username, email }) => {
  const existingUser = await User.findOne({
    where: {
      [Op.or]: [
        { username },
        { email }
      ]
    }
  })
  if (existingUser) {
    throw new Error('用户名或邮箱已存在')
  }
}

// 用户注册
const fn_UserRegister = async ctx => {
  const { username, password, email } = ctx.request.body
  try {
    await validateUserData({ username, password, email })
    await checkUserExists({ username, email })
    const hashedPassword = await argon2.hash(password)
    const user = await User.create({ username, password: hashedPassword, email })
    ctx.status = 201
    ctx.body = { message: '注册成功', user }
  } catch (error) {
    handleError(ctx, error.message)
  }
}

// 用户登录
const fn_UserLogin = async ctx => {
  const { username, password } = ctx.request.body
  try {
    const user = await User.findOne({ where: { username } })
    if (!user) {
      handleError(ctx, '用户名不存在')
      return
    }
    const isPasswordValid = await argon2.verify(user.password, password)
    if (!isPasswordValid) {
      handleError(ctx, '密码错误')
      return
    }
    user.lastLogin = new Date()
    await user.save()
    const token = jwt.sign(
      {
        userId: user.id,
        username: user.username
      },
      secret,
      { expiresIn: '1h' }
    )
    ctx.status = 201
    ctx.body = { message: '登录成功', token }
  } catch (error) {
    handleError(ctx, '登录失败')
  }
}

// 导出路由对象数组
export default [
  {
    method: 'post',
    url: '/api/user/register',
    fn: fn_UserRegister
  },
  {
    method: 'post',
    url: '/api/users/login',
    fn: fn_UserLogin
  }
]